(function ( exports ) {

    function ResponseBase ( messageName ) {
        this.isFaulted = false;
        this.error = null;
        this.responseName = messageName;
    }

    ResponseBase.prototype = {
        deserialize: function ( node ) {
            var tmpNode = node.node('Fault');

            if ( typeof tmpNode != 'undefined' ) {
                this.isFaulted = true;
                this.error = (new COSA.RootFault()).deserialize(tmpNode.namedNodes());
            }
            else {
                tmpNode = node.node('ExecuteResponse.ExecuteResult.Results');
                this.parseResponse(tmpNode);
            }

            return this;
        },
        deserializeMultiple: function ( node ) {
            var tmpNode = node.node('Fault');

            if ( typeof tmpNode.attr('i:nil') == 'undefined' ){
                this.isFaulted = true;
                this.error = (new COSA.Fault()).deserialize(tmpNode.namedNodes());
            }
            else {
                tmpNode = node.node('Response.Results');

                this.parseResponse(tmpNode);
            }

            return this;
        },
        parseResponse: function ( responseBody ) {}
    };

    function CustomResponse ( messageName ) {
        ResponseBase.call(this, messageName);
    }

    COSA.Util.deriveOverride(ResponseBase, CustomResponse, {
        parseResponse: function ( resultNode ) {
            var keyNodes = resultNode.keyValueCollection();

            for ( var key in keyNodes ) {
                var nilAttr = keyNodes[key].attr('i:nil'),
                    typeAttr = keyNodes[key].attr('i:type'), typeSplit;

                if ( typeof nilAttr != 'undefined' ) {
                    this[key] = null;
                }
                else {
                    typeSplit = typeAttr.split(':');
                    switch ( typeSplit[1] ) {
                        case 'int':
                            this[key] = keyNodes[key].toInt();
                            break;
                        case 'decimal':
                        case 'double':
                            this[key] = keyNodes[key].toDouble();
                            break;
                        case 'boolean':
                            this[key] = keyNodes[key].toBoolean();
                            break;
                        case 'EntityReference':
                            this[key] = keyNodes[key].toEntityReference();
                            break;
                        case 'dateTime':
                            this[key] = keyNodes[key].toDateTime();
                            break;
                        default:
                            this[key] = keyNodes[key].text();
                            break;
                    }
                }
            }
        }
    });

    exports.ResponseBase = ResponseBase;
    exports.CustomResponse = CustomResponse;

})(COSA.Response);
